package com.yazi.mxz.common.service.impl;

import javax.annotation.Resource;

import com.myframework.smhj.common.exception.MyException;
import com.myframework.smhj.common.tool.DateUtil;
import com.myframework.smhj.hibernate.dao.BasicService;
import com.myframework.smhj.hibernate.dao.Dao;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.yazi.mxz.common.db.dao.SpecDao;
import com.yazi.mxz.common.db.dao.SpecTypeDao;
import com.yazi.mxz.common.entity.ValueFactory;
import com.yazi.mxz.common.entity.beans.Company;
import com.yazi.mxz.common.entity.beans.Goods;
import com.yazi.mxz.common.entity.beans.Spec;
import com.yazi.mxz.common.entity.beans.SpecType;
import com.yazi.mxz.common.entity.beans.Store;
import com.yazi.mxz.common.entity.beans.StoreGoods;
import com.yazi.mxz.common.service.SpecService;

/**
 * Service实现：商品规格
 *
 * @author mo_yq5
 * @since 2016年6月3日
 */
@Service("specService")
public class SpecServiceImpl extends BasicService<Spec> implements SpecService {
	private static Logger log = LoggerFactory.getLogger(SpecServiceImpl.class);
	
	@Resource
	SpecDao specDao;
	@Resource
	SpecTypeDao specTypeDao;

	@Override
	protected Dao<Spec> getDao() {
		return specDao;
	}

	/**
	 * 本不方法未检查参数对象的合法性，因此在调用此方法前请自行做好合法性检查
	 */
	@Override
	public Spec addOrEdit(Spec spec) throws MyException {
		Spec dest;
		final Long specId = spec.getSpecId();
		if (null == specId) {// 添加
			log.debug("addOrEdit->add：name={}", spec.getName());
			ValueFactory.validate(spec);
			spec.setSpecId(null);
			spec.setUpdateTime(DateUtil.getTimeStamp());
			dest = specDao.persist(spec);
		} else {// 编辑
			log.debug("addOrEdit->edit：specId={}, name={}", specId, spec.getName());
			dest = specDao.get(specId);
			ValueFactory.combine(spec, dest);
			dest.setUpdateTime(DateUtil.getTimeStamp());
			specDao.merge(dest);
		}
		return dest;
	}
	
	@Override
	public Spec addOrEditByCompany(Company company, Spec spec) throws MyException {
		if (null == spec.getSpecId()) {// 添加
			// 必然是要求指定规格类型的，所以要（从企业方面）检查指定的规格类型是否合法
			checkSpecType4Company(company, spec.getSpecType().getSpecTypeId());
			
		} else {// 编辑
			// 如果编辑时重新指定了规格类型，同样需要（从企业方面）检查指定的规格类型的合法性
			if (null != spec.getSpecType()) {
				checkSpecType4Company(company, spec.getSpecType().getSpecTypeId());
			}
		}
		spec.getSpecType().getStoreGoods().getStore();
		return addOrEdit(spec);
	}
	
	@Override
	public Spec addOrEditByStore(Store store, Spec spec) throws MyException {
		if (null == spec.getSpecId()) {// 添加
			// 必然是要求指定规格类型的，所以要（从店铺方面）检查指定的规格类型是否合法
			checkSpecType4Store(store, spec.getSpecType().getSpecTypeId());
			
		} else {// 编辑
			// 如果编辑时重新指定了规格类型，同样需要（从店铺方面）检查指定的规格类型的合法性
			if (null != spec.getSpecType()) {
				checkSpecType4Store(store, spec.getSpecType().getSpecTypeId());
			}
		}
		return addOrEdit(spec);
	}
	
	/**
	 * 检查要求指定的规格类型（ID）必须属于指定店铺<br>
	 * 不属于则抛出<code>MyException</code>
	 * @since 2016年6月3日
	 * @param store 店铺
	 * @param specTypeId 被检查的规格类型ID
	 * @throws MyException
	 */
	private void checkSpecType4Store(Store store, Long specTypeId) throws MyException {
		SpecType specType = specTypeDao.get(specTypeId);
		StoreGoods storeGoods = specType.getStoreGoods();
		// 规格类型必须是店铺商品的，而且店铺商品必须是指定店铺的
		if (null == storeGoods || !storeGoods.getStore().equals(store)) {
			throw new MyException();
		}
	}
	
	/**
	 * 检查要求指定的规格类型（ID）必须属于指定企业<br>
	 * 不属于则抛出<code>MyException</code>
	 * @since 2016年6月3日
	 * @param company 企业
	 * @param specTypeId 被检查的规格类型ID
	 * @throws MyException
	 */
	private void checkSpecType4Company(Company company, Long specTypeId) throws MyException {
		SpecType specType = specTypeDao.get(specTypeId);
		Goods goods = specType.getGoods();
		// 规格类型必须是企业商品的，而且商品必须是指定企业的
		if (null == goods || !goods.getCompany().equals(company)) {
			throw new MyException();
		}
	}
	
}
